﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Data;
using AvalonDock;
using Caliburn.Core.Metadata;
using Caliburn.PresentationFramework.ApplicationModel;
using Microsoft.Windows.Controls.Ribbon;
using XWord.GUI.Views;
using Luna.WPF.ApplicationFramework;
using XWord.WPF.ApplicationFramework;

namespace XWord.GUI.Presenters
{
    [View(typeof(DockSiteView))]
    [Singleton(typeof(IDockSitePresenter))]
    public class DockSitePresenter : Presenter, IDockSitePresenter
    {

        private readonly Dictionary<IPresenter, ManagedContent> _cache2 = new Dictionary<IPresenter, ManagedContent>();
        private readonly IViewStrategy _viewStrategy;
        private readonly IBinder _binder;
        private Microsoft.Windows.Controls.Ribbon.Ribbon _ribbon;
        private DockablePane _leftPane;
        private DockablePane _rightPane;
        private DocumentPane _documentPane;

        public DockSitePresenter(IViewStrategy viewStrategy, IBinder binder)
        {
            _viewStrategy = viewStrategy;
            _binder = binder;
        }

        private DateTime _watchPoint;
        public DateTime WatchPoint
        {
            get { return _watchPoint; }
            set
            {
                if (value == default(DateTime)) return;
                _watchPoint = value;
                NotifyOfPropertyChange("WatchPoint");
            }
        }

        private Presenter _activePresenter;
        public Presenter ActivePresenter
        {
            get { return _activePresenter; }
            private set
            {
                _activePresenter = value;
                this.NotifyOfPropertyChange("ActivePresenter");
            }
        }

        public override void ViewLoaded(object view, object context)
        {

            var window = view as DockSiteView;

            _ribbon = window.ribbon;
            _leftPane = window.leftPane;
            _rightPane = window.rightPane;
            _documentPane = window.documentPane;
        }

        private static IPresenter GetPresenter(object view)
        {
            var fe = view as FrameworkElement;
            if (fe == null)
                throw new ArgumentNullException("view");
            var presenter = fe.DataContext as IPresenter;
            if (presenter == null)
                throw new Exception("Properties.Resources.NullRootModelException");
            return presenter;
        }

        private void CreateRibbonTab(object rootModel)
        {
            var view = _viewStrategy.GetView(rootModel, null, null);

            _binder.Bind(rootModel, view, null);

            var presenter = rootModel as IPresenter;
            if (presenter != null)
            {
                if (view is RibbonTab)
                {
                    _ribbon.Items.Add(view);
                    presenter.Initialize();
                }

            }
        }

        private ManagedContent CreateDockingPane(object rootModel)
        {
            var view = _viewStrategy.GetView(rootModel, null, null);

            _binder.Bind(rootModel, view, null);

            var presenter = rootModel as IPresenter;
            if (presenter != null)
            {
                if (_cache2.ContainsKey(presenter))
                    return _cache2[presenter];
                var metadata = view.GetDockingWindowMetadata();

                ManagedContent toolWindow = null;

                if (metadata == null)
                {
                    toolWindow = new DocumentContent() { Content = view };
                    _documentPane.Items.Add(toolWindow);
                }
                else
                {
                    if (metadata.IsToolWindow)
                    {
                        toolWindow = new DockableContent() { Content = view };
                    }
                    switch (metadata.DefaultDock)
                    {
                        case DockSiteDock.Left:
                            _leftPane.Items.Add(toolWindow);
                            break;
                        case DockSiteDock.Right:
                            _rightPane.Items.Add(toolWindow);
                            break;
                    }
                }
                toolWindow.SetBinding(
                 ManagedContent.TitleProperty,
                 new Binding
                 {
                     BindsDirectlyToSource = true,
                     Source = presenter.DisplayName,
                     Mode = BindingMode.OneWay
                 });


                if (!(presenter as PresenterBase).IsInitialized)
                {
                    presenter.Initialize();
                }

                _cache2[presenter] = toolWindow;
                return toolWindow;
            }

            return null;
        }

        public void Show(object rootModel)
        {
            CreateDockingPane(rootModel);
            return;

            //dockingWindow
            //dockingWindow.Open();
            //dockingWindow.Activate();

            //if (FrameworkElementService.GetIsFirstVisit(dockingWindow))
            //{
            //    var view = _viewStrategy.GetView(rootModel, null, null);
            //    var metadata = view.GetDockingWindowMetadata();
            //    if (metadata != null)
            //    {
            //        ResizeSlots();
            //    }
            //    FrameworkElementService.SetIsFirstVisit(dockingWindow, false);
            //}
        }

        //public void Show(object rootModel)
        //{
        //    var dockingWindow = CreateDockingWindow(rootModel, _dockSite);

        //    dockingWindow.Open();
        //    dockingWindow.Activate();

        //    if (FrameworkElementService.GetIsFirstVisit(dockingWindow))
        //    {
        //        var view = _viewStrategy.GetView(rootModel, null, null);
        //        var metadata = view.GetDockingWindowMetadata();
        //        if (metadata != null)
        //        {
        //            ResizeSlots();
        //        }
        //        FrameworkElementService.SetIsFirstVisit(dockingWindow, false);
        //    }
        //}

        public void ResizeSlots()
        {
            //IList<DependencyObject> descendents = VisualTreeHelperExtended.GetAllDescendants(this._dockSite, typeof(SplitContainer));
            //if (null != descendents)
            //{
            //    foreach (SplitContainer splitContainer in descendents)
            //    {
            //        splitContainer.ResizeSlots();
            //    }
            //}
        }

        public void ShowRibbon(object rootModel)
        {
            CreateRibbonTab(rootModel);
        }

        public void Activate(object presenter)
        {
            var item = _cache2.FirstOrDefault(o => o.Key.Equals(presenter));
            //if (Equals(item, default(KeyValuePair<IPresenter, DockingWindow>))) return;

            var dockingWindow = item.Value;
            dockingWindow.Activate();
            //dockingWindow.Activate(false);
        }

        public T GetActiveModel<T>() where T : class
        {
            //var item = _cache2.FirstOrDefault(o => o.Key.GetType().GetInterfaces().Contains(typeof(T)));
            //if (Equals(item, default(KeyValuePair<T, DockingWindow>)))
            //    return default(T);

            return null;
        }

        public T FirstOrDefault<T>(Func<T, bool> predicate) where T : IPresenter
        {
            var item = _cache2.FirstOrDefault(o => o.Key.GetType().GetInterfaces().Contains(typeof(T)));
            //if (Equals(item, default(KeyValuePair<T, DockingWindow>)))
            //    return default(T);

            return (T)item.Key;
        }

        protected override void OnShutdown()
        {
            base.OnShutdown();
        }
    }
}